package celiasoft.itasalib.query;

import java.util.Date;

import android.content.Context;
import celiasoft.itasalib.structures.SubsVersion;

public class QueryFactory {

	private final RawQueryFactory _factory;
	private static QueryFactory _instance = null;
	private String _authcode = null;
	
	public static QueryFactory getInstance(Context context, String apikey){
		
		if(_instance == null){
			_instance = new QueryFactory(context.getApplicationContext(), apikey);
		}
		
		return _instance;
	}
	
	private QueryFactory(Context context, String apikey) {
		
		this._factory = RawQueryFactory.getInstance(context, apikey);
		
	}
	
	
	/* SHOWS */
	
	/**
	 * @return a query for all available shows.
	 */
	public AllShowsQuery makeAllShowsQuery(){
		AllShowsQuery query = (AllShowsQuery) this._factory.makeQuery(QueryType.SHOW_ALL);
		return query;
	}
	
	/**
	 * @param showId The show's id.
	 * @return a query for a single show.
	 */
	public SingleShowQuery makeSingleShowQuery(int showId){
		SingleShowQuery query = (SingleShowQuery) this._factory.makeQuery(QueryType.SHOW_SINGLE);
		query.setShowId(showId);
		
		return query;
	}
	
	/**
	 * @param showId The show's id.
	 * @return a query for the main thumbnail of selected show, as a Bitmap.
	 */
	public ShowThumbQuery makeThumbShowQuery(int showId){
		ShowThumbQuery query = (ShowThumbQuery) this._factory.makeQuery(QueryType.SHOW_THUMB);
		query.setShowId(showId);
		
		return query;
	}
	
	/**
	 * @param searchQuery the query string to search shows.
	 * @return a query for searching a show. It returns only results on first page.
	 */
	public SearchShowQuery makeSearchShowQuery(String searchQuery){
		return makeSearchShowQuery(searchQuery, 1);
	}
	
	/**
	 * @param searchQuery the query string to search shows.
	 * @param page the result page number
	 * @return a query for searching a show.
	 */
	public SearchShowQuery makeSearchShowQuery(String searchQuery, int page){
		SearchShowQuery query = (SearchShowQuery) this._factory.makeQuery(QueryType.SHOW_SEARCH);
		query.setQuerySearch(searchQuery);
		query.setPage(page);
		
		return query;
	}
	
	/* NEWS */
	
	/**
	 * @return a query for searching a news. It returns only results on first page.
	 */
	public AllPageNewsQuery makeAllPageNewsQuery(){
		return makeAllPageNewsQuery(1);
	}
	
	/**
	 * @param page the result page number
	 * @return a query for all available news, page by page.
	 */
	public AllPageNewsQuery makeAllPageNewsQuery(int page){
		AllPageNewsQuery query = (AllPageNewsQuery) this._factory.makeQuery(QueryType.NEWS_ALL_PAGE);
		query.setPage(page);
		return query;
	}
	
	/**
	 * @param showId The show's id.
	 * @return a query for a single show.
	 */
	public SingleNewsQuery makeSingleNewsQuery(int newsId){
		SingleNewsQuery query = (SingleNewsQuery) this._factory.makeQuery(QueryType.NEWS_SINGLE);
		query.setNewsId(newsId);
		
		return query;
	}
	
	/**
	 * @param searchQuery the query string to search news.
	 * @param page the result page number
	 * @return a query for searching a news.
	 */
	public SearchNewsQuery makeSearchNewsQuery(String searchQuery, int page){
		SearchNewsQuery query = (SearchNewsQuery) this._factory.makeQuery(QueryType.NEWS_SEARCH);
		query.setQuerySearch(searchQuery);
		query.setPage(page);
		
		return query;
	}
	
	/* SUBS */
	
	/**
	 * @param showId the id of the show which subs we are looking for.
	 * @return a query for available subs for given show. It returns only results on first page.
	 */
	public AllPageShowSubsQuery makeAllPageShowSubsQuery(int showId){
		return makeAllPageShowSubsQuery(showId, 1, SubsVersion.NONE);
	}
	
	/**
	 * @param showId the id of the show which subs we are looking for.
	 * @param page the result page number
	 * @return a query for all available subs for given show, page by page.
	 */
	public AllPageShowSubsQuery makeAllPageShowSubsQuery(int showId, int page){
		return makeAllPageShowSubsQuery(showId, page, SubsVersion.NONE);
	}
	
	/**
	 * @param showId the id of the show which subs we are looking for.
	 * @param page the result page number
	 * @param version version of sub we are looking for
	 * @return a query for all available subs for given show, page by page.
	 */
	public AllPageShowSubsQuery makeAllPageShowSubsQuery(int showId, int page, SubsVersion version){
		AllPageShowSubsQuery query = (AllPageShowSubsQuery) this._factory.makeQuery(QueryType.SUBS_LIST_PAGES);
		query.setShowId(showId);
		query.setPage(page);
		query.setSubsVersion(version);
		return query;
	}
	
	/**
	 * @param subId The sub's id.
	 * @return a query for a specific sub.
	 */
	public SingleShowSubQuery makeSingleShowSubQuery(int subId){
		SingleShowSubQuery query = (SingleShowSubQuery) this._factory.makeQuery(QueryType.SUBS_SINGLE);
		query.setShowId(subId);
		return query;
	}
	
	/**
	 * @param searchQuery the query to search of needed sub.
	 * @param showId the id of the show which subs we are looking for.
	 * @param page the result page number
	 * @param version version of sub we are looking for
	 * @return a query for all available subs for given show, page by page.
	 */
	public SearchShowSubsQuery makeSearchShowSubsQuery(String searchQuery, int showId, int page, SubsVersion version){
		SearchShowSubsQuery query = (SearchShowSubsQuery) this._factory.makeQuery(QueryType.SUBS_SEARCH);
		query.setShowId(showId);
		query.setPage(page);
		query.setSubsVersion(version);
		query.setQuerySearch(searchQuery);
		return query;
	}
	
	/* LOGIN */
	
	/**
	 * @param username username
	 * @param password password
	 * @return a query to login and get the authcode needed for myitasa and user queries. 
	 */
	public LoginQuery makeLoginQuery(String username, String password){
		LoginQuery query = (LoginQuery) this._factory.makeQuery(QueryType.LOGIN);
		query.setUsername(username);
		query.setPassword(password);
		
		return query;
	}
	
	
	public void initializeAuthcode(String authcode){
		this._authcode =  authcode;
	}
	
	/* USER */
	
	/**
	 * This query works only if authcode was previously initialized using initializedAuthcode().
	 * @return a query for own user data.  
	 * @throws IllegalArgumentException if authcode was not initialized.
	 */
	public OwnUserQuery makeOwnUserQuery(){
		
		if(this._authcode == null)
			throw new IllegalArgumentException();
		
		return makeOwnUserQuery(this._authcode);
	}
	
	/**
	 * @param authcode key needed to access protected data see makeLoginQuery()
	 * @return a query for own user data.
	 */
	public OwnUserQuery makeOwnUserQuery(String authcode){
		OwnUserQuery query = (OwnUserQuery) this._factory.makeQuery(QueryType.USER_THIS);
		query.setAuthcodeKey(authcode);
		
		return query;
	}
	
	/**
	 * This query works only if authcode was previously initialized using initializedAuthcode().
	 * @param userId the id of user which data we are looking for
	 * @return a query for needed user data.
	 * @throws IllegalArgumentException if authcode was not initialized.
	 */
	public SingleUserQuery makeSingleUserQuery(int userId){
		if(this._authcode == null)
			throw new IllegalArgumentException();
		
		return makeSingleUserQuery(this._authcode, userId);
	}
	
	/**
	 * @param userId the id of user which data we are looking for
	 * @param authcode key needed to access protected data see makeLoginQuery()
	 * @return a query for needed user data.
	 */
	public SingleUserQuery makeSingleUserQuery(String authcode, int userId){
		SingleUserQuery query = (SingleUserQuery) this._factory.makeQuery(QueryType.USER_SINGLE);
		query.setAuthcodeKey(authcode);
		query.setUserId(userId);
		
		return query;
	}
	
	/* MYITASA */
	
	/**
	 * This query works only if authcode was previously initialized using initializedAuthcode().
	 * @return a query for the shows user likes (myitasa).
	 * @throws IllegalArgumentException if authcode was not initialized.
	 */
	public MyItasaShowsQuery makeMyItasaShowsQuery(){
		
		if(this._authcode == null)
			throw new IllegalArgumentException();
		
		return makeMyItasaShowsQuery(this._authcode);
	}
	
	/**
	 * @param authcode key needed to access protected data see makeLoginQuery()
	 * @return a query for the shows user likes (myitasa).
	 */
	public MyItasaShowsQuery makeMyItasaShowsQuery(String authcode){
		MyItasaShowsQuery query = (MyItasaShowsQuery) this._factory.makeQuery(QueryType.MYITASA_SHOWS);
		query.setAuthcodeKey(authcode);
		
		return query;
	}
	
	
	/**
	 * This query works only if authcode was previously initialized using initializedAuthcode().
	 * @return a query for last released subs for shows user likes (myitasa). It shows only the first result page.
	 * @throws IllegalArgumentException if authcode was not initialized.
	 */
	public MyItasaLastSubsQuery makeMyItasaLastSubsQuery(){
		
		if(this._authcode == null)
			throw new IllegalArgumentException();
		
		return makeMyItasaLastSubsQuery(this._authcode, 1);
	}
	
	
	/**
	 * This query works only if authcode was previously initialized using initializedAuthcode().
	 * @param page the result page number
	 * @return a query for last released subs for shows user likes (myitasa), page by page..
	 * @throws IllegalArgumentException if authcode was not initialized.
	 */
	public MyItasaLastSubsQuery makeMyItasaLastSubsQuery(int page){
		
		if(this._authcode == null)
			throw new IllegalArgumentException();
		
		return makeMyItasaLastSubsQuery(this._authcode, page);
	}
	
	/**
	 * @param authcode key needed to access protected data see makeLoginQuery()
	 * @param page the result page number
	 * @return a query for last released subs for shows user likes (myitasa), page by page..
	 */
	public MyItasaLastSubsQuery makeMyItasaLastSubsQuery(String authcode, int page){
		MyItasaLastSubsQuery query = (MyItasaLastSubsQuery) this._factory.makeQuery(QueryType.MYITASA_LAST_SUBS);
		query.setAuthcodeKey(authcode);
		query.setPage(page);
		
		return query;
	}
	
	
	
	/**
	 * This query works only if authcode was previously initialized using initializedAuthcode().
	 * @return a query for next episodes user likes (myitasa). It shows only the first result page.
	 * @throws IllegalArgumentException if authcode was not initialized.
	 */
	public MyItasaNextEpisodesQuery makeMyItasaNextEpisodesQuery(){
		
		if(this._authcode == null)
			throw new IllegalArgumentException();
		
		return makeMyItasaNextEpisodesQuery(this._authcode, 1);
	}
	
	
	/**
	 * This query works only if authcode was previously initialized using initializedAuthcode().
	 * @param page the result page number
	 * @return a query for next episodes user likes (myitasa), page by page.
	 * @throws IllegalArgumentException if authcode was not initialized.
	 */
	public MyItasaNextEpisodesQuery makeMyItasaNextEpisodesQuery(int page){
		
		if(this._authcode == null)
			throw new IllegalArgumentException();
		
		return makeMyItasaNextEpisodesQuery(this._authcode, page);
	}
	
	/**
	 * @param authcode key needed to access protected data see makeLoginQuery()
	 * @param page the result page number
	 * @return a query for next episodes user likes (myitasa), page by page.
	 */
	public MyItasaNextEpisodesQuery makeMyItasaNextEpisodesQuery(String authcode, int page){
		MyItasaNextEpisodesQuery query = (MyItasaNextEpisodesQuery) this._factory.makeQuery(QueryType.MYITASA_NEXT_SHOWS);
		query.setAuthcodeKey(authcode);
		query.setPage(page);

		return query;
	}
	
	/**
	 * This query works only if authcode was previously initialized using initializedAuthcode().
	 * @param showId the id of show we want add to myitasa.
	 * @return a query for add show to myitasa.
	 * @throws IllegalArgumentException if authcode was not initialized.
	 */
	public MyItasaAddShowQuery makeMyItasaAddShowQuery(int showId){
		
		if(this._authcode == null)
			throw new IllegalArgumentException();
		
		return makeMyItasaAddShowQuery(this._authcode, showId);
		
	}
	
	/**
	 * @param authcode key needed to access protected data see makeLoginQuery()
	 * @param showId the id of show we want add to myitasa.
	 * @return a query for add show to myitasa.
	 */
	public MyItasaAddShowQuery makeMyItasaAddShowQuery(String authcode, int showId){
		return makeMyItasaAddShowQuery(authcode, showId, null);
	}
	
	/**
	 * @param authcode key needed to access protected data see makeLoginQuery()
	 * @param showId the id of show we want add to myitasa.
	 * @param version version of subtitles we want add (could be null).
	 * @return a query for add show to myitasa.
	 */
	public MyItasaAddShowQuery makeMyItasaAddShowQuery(String authcode, int showId, SubsVersion version){
		MyItasaAddShowQuery query = (MyItasaAddShowQuery) this._factory.makeQuery(QueryType.MYITASA_ADD_SHOW);
		query.setAuthcodeKey(authcode);
		query.setShowId(showId);
		query.setVersion(version);

		return query;
	}
	
	/**
	 * This query works only if authcode was previously initialized using initializedAuthcode().
	 * @param showId the id of show we want remove from myitasa.
	 * @return a query for remove show from myitasa.
	 * @throws IllegalArgumentException if authcode was not initialized.
	 */
	public MyItasaRemoveShowQuery makeMyItasaRemoveShowQuery(int showId){
		
		if(this._authcode == null)
			throw new IllegalArgumentException();
		
		return makeMyItasaRemoveShowQuery(this._authcode, showId);
		
	}
	
	/**
	 * @param authcode key needed to access protected data see makeLoginQuery()
	 * @param showId the id of show we want remove from myitasa.
	 * @return a query for remove show from myitasa.
	 */
	public MyItasaRemoveShowQuery makeMyItasaRemoveShowQuery(String authcode, int showId){
		return makeMyItasaRemoveShowQuery(authcode, showId, null);
	}
	
	/**
	 * @param authcode key needed to access protected data see makeLoginQuery()
	 * @param showId the id of show we want remove from myitasa.
	 * @param version version of subtitles we want remove (could be null).
	 * @return a query for remove show from myitasa.
	 */
	public MyItasaRemoveShowQuery makeMyItasaRemoveShowQuery(String authcode, int showId, SubsVersion version){
		MyItasaRemoveShowQuery query = (MyItasaRemoveShowQuery) this._factory.makeQuery(QueryType.MYITASA_REMOVE_SHOW);
		query.setAuthcodeKey(authcode);
		query.setShowId(showId);
		query.setVersion(version);

		return query;
	}
	
	
	
	/**
	 * @param day we want results nearby this day
	 * @return a query for next episodes scheduled.
	 */
	public CalendarQuery makeCalendarQuery(Date day){
		CalendarQuery query = (CalendarQuery) this._factory.makeQuery(QueryType.SHOWS_CALENDAR);
		query.setCalDay(day);

		return query;
	}
	
	/**
	 * @return a query for subs making current status.
	 */
	public TranslationsStatusQuery makeTranslationsStatusQuery(){
		TranslationsStatusQuery query = (TranslationsStatusQuery) this._factory.makeQuery(QueryType.TRANSLATIONS_STATUS);

		return query;
	}
	
}
